﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Xml;
using System.Windows.Documents;
using System.Text;
using System.Windows.Data;
using System.Windows.Controls.Primitives;
using System.Drawing.Text;
using System.Windows.Markup;
using System.Collections.Generic;
using SHomeWorkshop.LunarConcept.Tools;
using SHomeWorkshop.LunarConcept;
using SHomeWorkshop.LunarConcept.ModifingManager;
using SHomeWorkshop.LunarConcept.Controls;
using SHomeWorkshop.LunarConcept.Widgets;
using SHomeWorkshop.LunarConcept.Widgets.Interfaces;
using SHomeWorkshop.LunarConcept.Commands.TextCommands;

namespace SHomeWorkshop.LunarConcept.Dialogs
{
    /// <summary>
    /// 创建时间：2012年1月3日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：TextAreaEditor.xaml的交互逻辑代码。
    /// </summary>
    public partial class TextAreaEditor : Window
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// [构造方法]创建一个文本块的编辑区（编辑器）。
        /// </summary>
        /// <param name="editormanager">编辑器管理器。</param>
        /// <param name="widgets">传入要编辑的部件列表。</param>
        public TextAreaEditor(EditorManager editorManager,
            List<Widgets.Widget> selectedWidgets, string initializedText = null)
        {
            InitializeComponent();

            this.editorManager = editorManager;

            this.initializedText = initializedText;

            MaxWidth = PaperInfo.GetPaperInfo("Slide").LongSideWPFUnit;

            //禁用原来的快捷菜单。
            mainRTB.ContextMenu = null;

            this.selectedWidgets = selectedWidgets;

            InputMethod.SetIsInputMethodEnabled(mainRTB, true);

            //给边框添加变色效果，结果发现有打扰人的反面效果，于是改成只闪动两次。
            Brush myBrush = new SolidColorBrush();

            ColorAnimation myColorAnimation = new ColorAnimation();

            myColorAnimation.From = Colors.Transparent;

            myColorAnimation.To = Colors.Gray;
            myColorAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(200));
            myColorAnimation.AutoReverse = true;
            myColorAnimation.RepeatBehavior = new RepeatBehavior(1);

            //将动画应用到画刷（Brush）的“Color”属性。
            #region 没必要用动画
            //myBrush.BeginAnimation(SolidColorBrush.ColorProperty, myColorAnimation);
            //outBorder.BorderBrush = myBrush;

            //if (textWidgets == null)
            //{
            //    mainRTB.Selection.Text = "没有指定要编辑的文本块！";
            //    mainRTB.IsEnabled = false;
            //    btnOKTool.IsEnabled = false;
            //    return;
            //}

            //if (textWidgets.Count <= 0)
            //{
            //    mainRTB.Selection.Text = "没有指定要编辑的文本块！";
            //    mainRTB.IsEnabled = false;
            //    btnOKTool.IsEnabled = false;
            //    return;
            //} 
            #endregion

            Globals.SwitchInputMethod(true);

            #region 列出所有可用字体，已有更好方案，已移动到Globals类中。2012年7月31日。

            //InstalledFontCollection clsInstalledFontCollection = new InstalledFontCollection();
            //System.Drawing.FontFamily[] affInstalledFont = clsInstalledFontCollection.Families;

            //StringBuilder sb = new StringBuilder();
            //foreach (System.Drawing.FontFamily f in affInstalledFont)
            //{
            //    ComboFontItem cfi = new ComboFontItem(f.Name, new System.Windows.Media.FontFamily(f.Name));
            //    cbFont.Items.Add(cfi);
            //}

            //// 注意：上面使用的是System.Drawing下的FontFamily类，
            //// 而下面使用的是System.Window.Media下的FontFamily。
            //// 好不容易才找到如何解决问题的办法。
            //LanguageSpecificStringDictionary fontDics = this.FontFamily.FamilyNames;
            //if (fontDics.ContainsKey(XmlLanguage.GetLanguage("zh-cn")))
            //{
            //    string fontName = null;
            //    if (fontDics.TryGetValue(XmlLanguage.GetLanguage("zh-cn"), out fontName))
            //    {
            //        Globals.SysFontFamily = fontName;
            //    }
            //}

            // 字体框和字号框的初始化老造成意外问题。
            //if (cbFont.Items.Contains(Globals.SysFontFamily))
            //{
            //    cbFont.SelectedItem = Globals.SysFontFamily;
            //}
            //cbFontSize.SelectedIndex = 2;//字号默认是12，索引是2。

            #endregion

            //绑定拾色器相关事件。
            this.colorPickerPopup.Child = colorPicker;
            this.colorPicker.Closed += new EventHandler<EventArgs>(colorPicker_Closed);
            this.colorPicker.ColorPicked += new EventHandler<ColorPickedEventArgs>(colorPicker_ColorPicked);

            //初始化文本
            if (initializedText == null || initializedText.Length <= 0)
            {
                ReadLines();

                if (fontWeightIsSame && fontWeightAfterReaded != null)
                {
                    //如果所有文本片段的FontWeight都是相同的，则按最后一个设置。
                    this.mainRTB.FontWeight = fontWeightAfterReaded.Value;
                }
                else
                {
                    this.mainRTB.FontWeight = FontWeights.Normal;
                }

                this.mainRTB.SelectAll();
            }
            else
            {
                this.mainRTB.SelectAll();
                this.mainRTB.Selection.Text = "";
                this.mainRTB.AppendText(initializedText);

                //初始化字体。
                //foreach (ComboFontItem cfi in cbFont.Items)
                //{
                //    if (cfi.FontName == "SimSun")
                //    {
                //        cbFont.SelectedItem = cfi;
                //    }
                //}
            }

            mainRTB.Focus();

            //★★★★★这个事件的挂接必须在初始化文本之后，否则会导致字号不能同步的问题！！！
            cbFontSize.SelectionChanged += new SelectionChangedEventHandler(cbFontSize_SelectionChanged);
        }

        #endregion


        #region 字段与属性===================================================================================================

        /// <summary>
        /// 自定义拾色器使用的PopUp。
        /// </summary>
        private Popup colorPickerPopup = new Popup() { IsOpen = false };

        /// <summary>
        /// 自定义拾色器。
        /// </summary>
        private readonly ColorPicker colorPicker = new ColorPicker();

        /// <summary>
        /// 选定文本时，读取字体名称。此地应避免循环设定字体。
        /// </summary>
        private bool dontChangeFont = false;

        private EditorManager editorManager;

        /// <summary>
        /// 读取初始文本后，看要不要将主编辑区整个设置为Bold。
        /// </summary>
        private FontWeight? fontWeightAfterReaded = null;

        /// <summary>
        /// 如果初始文本所有的fontWdeight都是相同的，则应设置MainRTB初始fontWeight为fontWeightAfterReaded。
        /// </summary>
        private bool fontWeightIsSame = true;

        private List<Widgets.Widget> selectedWidgets;
        /// <summary>
        /// [只读]要编辑的文本块的列表。由构造方法传入。
        /// </summary>
        public List<Widgets.Widget> SelectedWidgets
        {
            get { return selectedWidgets; }
        }

        /// <summary>
        /// Ctrl+1-5更改此级别。在完成编辑时，将所有相关部件的标题层级设置为此值。
        /// 
        /// 之所以是可空类型，这是因为用户可能根本不需要更改这个值。此时应保持各部件原来的标题层级。
        /// </summary>
        private Enums.TitleStyle? titleLevel = null;

        /// <summary>
        /// 所编辑部件的前景色。
        /// 如果编辑结束时，某个文本碎片的前景色等于所编辑部件的前景色，那么，将不会把色彩名称写入Xml。
        /// ——这样做的目的是允许部件的“前景色”属性控制部分文本的色彩。
        /// 
        /// ——但如果某个文本碎片（Run）设置了自己的色彩，那么，将会被记录在Xml中，部件的“前景色”属性将
        /// 不能控制这个Run的文本前景色。
        /// </summary>
        private Brush widgetForeColor;


        #region 用于定位拾色器的两个绑定

        private Binding textForegroundBinding = null;

        private Binding textBackgroundBinding = null;

        #endregion


        #endregion


        #region 方法=========================================================================================================

        private void btnBackground_Click(object sender, RoutedEventArgs e)
        {
            if (colorPickerPopup.IsOpen)
            {
                colorPickerPopup.IsOpen = false;
            }

            if (textBackgroundBinding == null)
            {
                textBackgroundBinding = new Binding();
                textBackgroundBinding.Source = btnBackground;
            }

            colorPickerPopup.SetBinding(Popup.PlacementTargetProperty, textBackgroundBinding);

            ColorPicker colorpicker = colorPickerPopup.Child as ColorPicker;
            colorpicker.DestAction = ColorPicker.Destination.BackColor;
            colorPickerPopup.IsOpen = true;
        }

        private void btnCancelTool_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            CloseCancel();
        }

        private void CloseCancel()
        {
            this.DialogResult = false;
            Globals.SwitchInputMethod(false);
            this.Close();
        }

        private void btnCut_Click(object sender, RoutedEventArgs e)
        {
            mainRTB.Cut();
        }

        private void btnCopy_Click(object sender, RoutedEventArgs e)
        {
            mainRTB.Copy();
        }

        private void btnBold_Click(object sender, RoutedEventArgs e)
        {
            FontWeight fw = (FontWeight)mainRTB.Selection.GetPropertyValue(TextElement.FontWeightProperty);

            if (fw == FontWeights.Bold)
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Normal);
            }
            else
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
            }
        }

        private void btnBottomMark_Click(object sender, RoutedEventArgs e)
        {
            var currentAlignment = mainRTB.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);

            BaselineAlignment newAlignment;

            if (currentAlignment == DependencyProperty.UnsetValue)
            {
                newAlignment = BaselineAlignment.Bottom;
            }
            else
            {
                newAlignment =
                ((BaselineAlignment)currentAlignment == BaselineAlignment.Bottom) ?
                    BaselineAlignment.Baseline : BaselineAlignment.Bottom;
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, newAlignment);

            if (newAlignment == BaselineAlignment.Baseline)
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, mainRTB.FontSize);
            }
            else
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, mainRTB.FontSize / 2);
            }
        }

        private void btnForeground_Click(object sender, RoutedEventArgs e)
        {
            if (colorPickerPopup.IsOpen)
            {
                colorPickerPopup.IsOpen = false;
            }

            if (textForegroundBinding == null)
            {
                textForegroundBinding = new Binding();
                textForegroundBinding.Source = btnForeground;
            }

            colorPickerPopup.SetBinding(Popup.PlacementTargetProperty, textForegroundBinding);

            ColorPicker colorpicker = colorPickerPopup.Child as ColorPicker;
            colorpicker.DestAction = ColorPicker.Destination.ForeColor;
            colorPickerPopup.IsOpen = true;
        }

        private void btnItalic_Click(object sender, RoutedEventArgs e)
        {
            FontStyle fs = (FontStyle)mainRTB.Selection.GetPropertyValue(TextElement.FontStyleProperty);

            if (fs == FontStyles.Italic)
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Normal);
            }
            else
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Italic);
            }
        }

        private void btnOKTool_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            CloseOk();
        }

        private void CloseOk()
        {
            this.DialogResult = true;

            WriteLinesToAllWidgetsXmlData();
            Globals.SwitchInputMethod(false);
            this.Close();
        }

        private void btnPaste_Click(object sender, RoutedEventArgs e)
        {
            //mainRTB.Paste();
            //防止从应用程序外部粘贴不能识别的格式。因此只支持粘贴纯文本。
            mainRTB.Selection.Text = Clipboard.GetText(TextDataFormat.UnicodeText).Replace("\t", "    ");//禁止出现\t字符。
            TextRange sel = mainRTB.Selection;
            sel.Select(sel.End, sel.End);
            e.Handled = true;
        }

        private void btnRedo_Click(object sender, RoutedEventArgs e)
        {
            if (mainRTB.CanRedo)
            {
                mainRTB.Redo();
            }
        }

        private void btnStrikeLine_Click(object sender, RoutedEventArgs e)
        {
            TextDecorationCollection tc = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection;

            bool isStrikeline = false;

            var obj = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty);

            TextDecorationCollection tdCollection = obj as TextDecorationCollection;

            if (tdCollection != null || tdCollection.Count > 0)
            {
                foreach (TextDecoration td in tdCollection)
                {
                    if (td.Location == TextDecorationLocation.Strikethrough)
                    {
                        isStrikeline = true;
                        break;
                    }
                }
            }

            TextDecorationCollection newTC = new TextDecorationCollection();

            if (isStrikeline)
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    if (td.Location == TextDecorationLocation.Strikethrough)
                    {
                        continue;
                    }

                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }
            }
            else
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }

                newTC.Add(new TextDecoration() { Location = TextDecorationLocation.Strikethrough });
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, newTC);
        }

        private void btnTopMark_Click(object sender, RoutedEventArgs e)
        {
            var currentAlignment = mainRTB.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);

            BaselineAlignment newAlignment;

            if (currentAlignment == DependencyProperty.UnsetValue)
            {
                newAlignment = BaselineAlignment.Top;
            }
            else
            {
                newAlignment =
                    ((BaselineAlignment)currentAlignment == BaselineAlignment.Top) ?
                        BaselineAlignment.Baseline : BaselineAlignment.Top;
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, newAlignment);

            if (newAlignment == BaselineAlignment.Baseline)
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, mainRTB.FontSize);
            }
            else
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, mainRTB.FontSize / 2);
            }
        }

        private void btnUnderLine_Click(object sender, RoutedEventArgs e)
        {
            TextDecorationCollection tc = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection;

            bool isUnderline = false;

            var obj = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty);

            TextDecorationCollection tdCollection = obj as TextDecorationCollection;

            if (tdCollection != null || tdCollection.Count > 0)
            {
                foreach (TextDecoration td in tdCollection)
                {
                    if (td.Location == TextDecorationLocation.Underline)
                    {
                        isUnderline = true;
                        break;
                    }
                }
            }

            TextDecorationCollection newTC = new TextDecorationCollection();

            if (isUnderline)
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    if (td.Location == TextDecorationLocation.Underline)
                    {
                        continue;
                    }

                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }
            }
            else
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }

                newTC.Add(new TextDecoration() { Location = TextDecorationLocation.Underline });
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, newTC);
        }

        private void btnUndo_Click(object sender, RoutedEventArgs e)
        {
            if (mainRTB.CanUndo)
            {
                mainRTB.Undo();
            }
        }

        /// <summary>
        /// 生成某个段落的Xml文本。
        /// </summary>
        private void BuildOneParagraphInnerXml(StringBuilder sb, Paragraph paragraph)
        {
            foreach (Inline inline in paragraph.Inlines)
            {
                Run run = inline as Run;
                if (run != null && run.Text.Length > 0)
                {
                    sb.Append("<" + XmlTags.TextTag + " ");//不完整的tab，因为要考虑特性。

                    //取出各格式特性值。

                    // 如果当前Run的前景色与部件前景色一致，那就由部件控制前景色，不记入Xml中。
                    if (run.Foreground != this.widgetForeColor)
                    {
                        sb.Append(XmlTags.ForeColorTag + "=\"");
                        sb.Append(BrushManager.GetName(run.Foreground));
                        sb.Append("\" ");
                    }

                    sb.Append(XmlTags.BackColorTag + "=\"");
                    sb.Append(BrushManager.GetName(run.Background));
                    sb.Append("\" ");

                    if (editorManager == null || run.FontSize != editorManager.DefaultFontSize)
                    {
                        sb.Append(XmlTags.FontSizeTag + "=\"");
                        sb.Append(run.FontSize);
                        sb.Append("\" ");
                    }

                    sb.Append(XmlTags.FontWeightTag + "=\"");
                    sb.Append(run.FontWeight.ToString());
                    sb.Append("\" ");

                    sb.Append(XmlTags.FontStyleTag + "=\"");
                    sb.Append(run.FontStyle.ToString());
                    sb.Append("\" ");

                    if (editorManager == null || run.FontFamily.Source != editorManager.DefaultFontName)
                    {
                        sb.Append(XmlTags.FontNameTag + "=\"");
                        sb.Append(run.FontFamily.Source);
                        sb.Append("\" ");
                    }

                    if (run.TextDecorations != null && run.TextDecorations.Count > 0)
                    {
                        bool isStrikeLine = false;
                        bool isUnderLine = false;
                        foreach (TextDecoration td in run.TextDecorations)
                        {
                            if (td.Location == TextDecorationLocation.Underline)
                            {
                                isUnderLine = true;
                            }
                            else if (td.Location == TextDecorationLocation.Strikethrough)
                            {
                                isStrikeLine = true;
                            }
                        }

                        if (isStrikeLine)
                        {
                            sb.Append(XmlTags.StrikeLineTag + "=\"True\" ");
                        }

                        if (isUnderLine)
                        {
                            sb.Append(XmlTags.UnderLineTag + "=\"True\" ");
                        }
                    }

                    sb.Append(XmlTags.BaseLineAlignmentTag + "=\"");
                    sb.Append(run.BaselineAlignment.ToString());
                    sb.Append("\" ");

                    sb.Append(">");
                    sb.Append(XmlTools.ReplaceXmlChars(run.Text));
                    sb.Append("</" + XmlTags.TextTag + ">");
                }

            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            mainRTB.Selection.Text = (sender as Button).Content.ToString();
        }

        private void colorPicker_Closed(object sender, EventArgs e)
        {
            colorPickerPopup.IsOpen = false;
        }

        private void colorPicker_ColorPicked(object sender, ColorPickedEventArgs e)
        {
            colorPickerPopup.IsOpen = false;

            SetTextColor((sender as ColorPicker).DestAction, e.PickedColor);
        }

        private void cbFont_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //组合框中只有字体名称
            if (dontChangeFont) return;

            //FontFamily ff = new FontFamily((cbFont.SelectedItem as ComboFontItem).FontName);

            FontFamily ff = new FontFamily((cbFont.SelectedItem as FontInfo).FontName.ToString());

            mainRTB.Selection.ApplyPropertyValue(TextElement.FontFamilyProperty, ff);
        }

        private void cbFontSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbFontSize.SelectedItem != null)
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty,
                    double.Parse((cbFontSize.SelectedItem as ComboBoxItem).Content as string));
            }
            mainRTB.Focus();
        }

        private void mainRTB_KeyUp(object sender, KeyEventArgs e)
        {
            bool isShift = false, isCtrl = false;
            KeyboardDevice kd = e.KeyboardDevice;

            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if ((kd.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0)
            {
                isCtrl = true;
            }

            switch (e.Key)
            {
                case Key.OemPlus:
                    {
                        if (isCtrl)
                        {
                            if (isShift)
                            {
                                btnBottomMark_Click(null, null);
                                e.Handled = true;
                            }
                            else
                            {
                                btnTopMark_Click(null, null);
                                e.Handled = true;
                            }
                        }
                        break;
                    }
                case Key.T:
                    {
                        if (isCtrl && !isShift)
                        {
                            btnStrikeLine_Click(null, null);
                            e.Handled = true;
                        }
                        break;
                    }
                case Key.D0:
                    {
                        if (isCtrl && isShift == false)
                            this.FormatAsTitle(Enums.TitleStyle.MainTitle);
                        break;
                    }
                case Key.D1:
                    {
                        if (isCtrl && isShift == false)
                            this.FormatAsTitle(Enums.TitleStyle.T1);
                        break;
                    }
                case Key.D2:
                    {
                        if (isCtrl && isShift == false)
                            this.FormatAsTitle(Enums.TitleStyle.T2);
                        break;
                    }
                case Key.D3:
                    {
                        if (isCtrl && isShift == false)
                            this.FormatAsTitle(Enums.TitleStyle.T3);
                        break;
                    }
                case Key.D4:
                    {
                        if (isCtrl && isShift == false)
                            this.FormatAsTitle(Enums.TitleStyle.T4);
                        break;
                    }
                case Key.D5:
                    {
                        if (isCtrl && isShift == false)
                            this.FormatAsTitle(Enums.TitleStyle.T5);
                        break;
                    }
                case Key.D6:
                    {
                        if (isCtrl && isShift == false)
                            this.FormatAsTitle(Enums.TitleStyle.Normal);
                        break;
                    }
            }
        }

        private void FormatAsTitle(Enums.TitleStyle titleStyle)
        {
            double fontSize = TitleManager.GetFontSize(titleStyle);
            string fontName = TitleManager.GetFontName(titleStyle);
            FontFamily fontFamily = new System.Windows.Media.FontFamily(fontName); ;
            FontWeight fontWeight = TitleManager.GetFontWeight(titleStyle);

            foreach (Block block in mainDoc.Blocks)
            {
                Paragraph paragraph = block as Paragraph;
                if (paragraph == null) continue;

                foreach (Inline inline in paragraph.Inlines)
                {
                    Run run = inline as Run;
                    if (run == null) continue;

                    run.FontSize = fontSize;
                    run.FontFamily = fontFamily;
                    run.FontWeight = fontWeight;
                }
            }

            mainRTB.FontFamily = fontFamily;
            mainRTB.FontSize = fontSize;
            mainRTB.FontWeight = fontWeight;

            titleLevel = titleStyle;
        }

        private void UnableTopOrBottomMark()
        {
            mainRTB.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Baseline);
        }

        private void UnableStraitLine()
        {
            TextDecorationCollection tc = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection;
            bool isStrikeline = false;
            var obj = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty);
            TextDecorationCollection tdCollection = obj as TextDecorationCollection;

            if (tdCollection != null || tdCollection.Count > 0)
            {
                foreach (TextDecoration td in tdCollection)
                {
                    if (td.Location == TextDecorationLocation.Strikethrough)
                    {
                        isStrikeline = true;
                        break;
                    }
                }
            }

            TextDecorationCollection newTC = new TextDecorationCollection();

            if (isStrikeline)
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    if (td.Location == TextDecorationLocation.Strikethrough)
                    {
                        continue;
                    }

                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, newTC);
        }

        private void UnableUnderLine()
        {
            TextDecorationCollection tc = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection;

            bool isUnderline = false;

            var obj = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty);

            TextDecorationCollection tdCollection = obj as TextDecorationCollection;

            if (tdCollection != null || tdCollection.Count > 0)
            {
                foreach (TextDecoration td in tdCollection)
                {
                    if (td.Location == TextDecorationLocation.Underline)
                    {
                        isUnderline = true;
                        break;
                    }
                }
            }

            TextDecorationCollection newTC = new TextDecorationCollection();

            if (isUnderline)
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    if (td.Location == TextDecorationLocation.Underline)
                    {
                        continue;
                    }

                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, newTC);
        }

        private void mainRTB_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            bool isShift = false, isCtrl = false, isAlt = false;
            KeyboardDevice kd = e.KeyboardDevice;

            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if ((kd.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0)
            {
                isCtrl = true;
            }

            if ((kd.GetKeyStates(Key.LeftAlt) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightAlt) & KeyStates.Down) > 0)
            {
                isAlt = true;
            }

            if (e.Key == Key.Enter)
            {
                if (isCtrl || isShift)
                {
                    //mainRTB.Selection.Text = "\r\n";
                    TextRange tr = new TextRange(mainRTB.Selection.Start, mainRTB.Selection.End);

                    var offset = tr.Start.GetPositionAtOffset(0, LogicalDirection.Forward);

                    tr.Text = "\r\n";

                    mainRTB.CaretPosition = tr.End;

                    e.Handled = true;
                }
                else
                {
                    CloseOk();
                    //e.Handled = true;
                }
            }

            if (e.Key == Key.Escape)
            {
                CloseCancel();
            }

            try
            {
                if (e.Key == Key.V && isCtrl && isShift == false)
                {
                    mainRTB.Selection.Text = Clipboard.GetText(TextDataFormat.UnicodeText).Replace("\t", "    ");//禁止出现\t字符。
                    TextRange sel = mainRTB.Selection;
                    sel.Select(sel.End, sel.End);
                    e.Handled = true;
                    return;
                }

                if (e.Key == Key.OemPeriod && isCtrl && isShift)
                {
                    object v = mainRTB.Selection.GetPropertyValue(TextElement.FontSizeProperty);

                    if (v == DependencyProperty.UnsetValue)
                    {
                        mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, 16.0);
                        return;
                    }
                    else
                    {
                        double oldFontSize = (double)v;
                        mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, oldFontSize + 2);
                        return;
                    }
                }

                if (e.Key == Key.OemComma && isCtrl && isShift)
                {
                    object v = mainRTB.Selection.GetPropertyValue(TextElement.FontSizeProperty);

                    if (v == DependencyProperty.UnsetValue)
                    {
                        mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, 16.0);
                        return;
                    }
                    else
                    {
                        double oldFontSize = (double)v;
                        mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, oldFontSize - 2);
                        return;
                    }
                }

                if (e.Key == Key.F1 && isCtrl && !isAlt && !isShift)
                {
                    btnStreamerBack_Click(sender, e);
                    return;
                }


                //打开命令输入面板。
                if (e.Key == Key.Back && isShift)
                {
                    commandPanel.Visibility = System.Windows.Visibility.Visible;
                    CbxQuickCommandBox.Focus();
                    e.Handled = true;
                    return;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("　　编辑器快捷键处理程序出现异常错误。异常信息如下：\r\n　　" + ex.Message +
                       "\r\n　　" + ex.StackTrace, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
        }

        private void mainRTB_SelectionChanged(object sender, RoutedEventArgs e)
        {
            FontFamily ff = mainRTB.Selection.GetPropertyValue(TextElement.FontFamilyProperty) as FontFamily;
            if (ff == null) return;

            if (cbFont.Items.Contains(ff.Source))
            {
                dontChangeFont = true;
                cbFont.SelectedItem = ff.Source;
                dontChangeFont = false;
            }

            var ofs = mainRTB.Selection.GetPropertyValue(TextElement.FontStyleProperty);
            if (ofs is FontStyle)
            {
                FontStyle fs = (FontStyle)ofs;
                if (fs == FontStyles.Italic)
                {
                    btnItalic.IsChecked = true;
                }
                else btnItalic.IsChecked = false;
            }
            else btnItalic.IsChecked = false;

            var ofw = mainRTB.Selection.GetPropertyValue(TextElement.FontWeightProperty);
            if (ofw is FontWeight)
            {
                FontWeight fw = (FontWeight)ofw;
                if (fw == FontWeights.Bold)
                {
                    btnBold.IsChecked = true;
                }
                else btnBold.IsChecked = false;
            }
            else btnBold.IsChecked = false;

            TextDecorationCollection tc = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection;
            if (tc == null)
            {
                btnUnderLine.IsChecked = false;
                btnStrikeLine.IsChecked = false;
            }
            else
            {
                bool isUnderLine = false;
                bool isStrikeLine = false;
                foreach (TextDecoration td in tc)
                {
                    if (td.Location == TextDecorationLocation.Underline)
                    {
                        isUnderLine = true; break;
                    }
                }

                foreach (TextDecoration td in tc)
                {
                    if (td.Location == TextDecorationLocation.Strikethrough)
                    {
                        isStrikeLine = true;
                    }
                }

                btnUnderLine.IsChecked = isUnderLine;
                btnStrikeLine.IsChecked = isStrikeLine;
            }
        }

        /// <summary>
        /// 从提供的文本块列表载入其中“活动”的那个文本块的文本内容为编辑器初始值。
        /// </summary>
        private void ReadLines()
        {
            bool mainRTBFontSetted = false;

            Widgets.Widget mainSelectedWidget = null;

            foreach (Widgets.Widget w in selectedWidgets)
            {
                if (w.IsMainSelected) mainSelectedWidget = w;
            }

            if (mainSelectedWidget == null && selectedWidgets.Count > 0)
            {
                mainSelectedWidget = selectedWidgets[0];
            }

            if (mainSelectedWidget == null) return;
            if (selectedWidgets.Contains(mainSelectedWidget) == false) return;

            widgetForeColor =
            mainRTB.Foreground = mainSelectedWidget.WidgetForeColor;
            if (mainSelectedWidget.WidgetBackColor == Brushes.Transparent)
            {
                if (mainSelectedWidget.MasterEditor != null && mainSelectedWidget.MasterEditor.MasterManager != null)
                {
                    mainRTB.Background = mainSelectedWidget.MasterEditor.MasterManager.DocumentBackground;
                }
                else
                {
                    mainRTB.Background = Brushes.Tomato;//得找个用户不太可能使用的。
                }
            }
            else
            {
                VisualBrush vbsh = mainSelectedWidget.WidgetBackColor as VisualBrush;
                if (vbsh != null)
                {
                    mainRTB.Background = BrushManager.GetVisualBrushBaseBrush(vbsh);
                }
                else
                {
                    mainRTB.Background = mainSelectedWidget.WidgetBackColor;//初始化前景色、背景色。
                }
            }

            XmlNode paragraphSetNode = mainSelectedWidget.XmlData.SelectSingleNode(XmlTags.ParagraphSetTag);
            if (paragraphSetNode == null)
            {
                ReadDefaultFontSizeAndFontFamily();
                return;
            }

            XmlNodeList paragraphNodes = paragraphSetNode.SelectNodes(XmlTags.ParagraphTag);

            if (paragraphNodes.Count == 0)
            {
                ReadDefaultFontSizeAndFontFamily();
                return;
            }

            switch (mainSelectedWidget.TitleLevel)
            {
                case Enums.TitleStyle.Normal:
                    {
                        foreach (XmlNode paragraphNode in paragraphNodes)
                        {
                            TextAlignment textAlignment = TextAlignment.Justify;
                            XmlAttribute attrTextAlignment = paragraphNode.GetAttribute(XmlTags.TextAlignmentTag);
                            if (attrTextAlignment != null)
                            {
                                textAlignment = (TextAlignment)Enum.Parse(typeof(TextAlignment), attrTextAlignment.Value);
                            }

                            XmlNodeList textNodes = paragraphNode.SelectNodes(XmlTags.TextTag);
                            if (textNodes == null || textNodes.Count <= 0)
                            {
                                Paragraph newParagraph = new Paragraph();
                                mainDoc.Blocks.Add(newParagraph);//添加个空段。
                                continue;
                            }

                            mainRTBFontSetted = ReadOneParagraph(mainRTBFontSetted, textNodes, textAlignment);
                        }
                        break;
                    }
                default://六个级别的标题
                    {
                        double fontSize = TitleManager.GetFontSize(mainSelectedWidget.TitleLevel);
                        FontWeight fontWeight = TitleManager.GetFontWeight(mainSelectedWidget.TitleLevel);
                        FontFamily fontFamily = TitleManager.GetFontFamily(mainSelectedWidget.TitleLevel);

                        foreach (XmlNode paragraphNode in paragraphNodes)
                        {
                            TextAlignment textAlignment = TextAlignment.Justify;
                            XmlAttribute attrTextAlignment = paragraphNode.GetAttribute(XmlTags.TextAlignmentTag);
                            if (attrTextAlignment != null)
                            {
                                textAlignment = (TextAlignment)Enum.Parse(typeof(TextAlignment), attrTextAlignment.Value);
                            }

                            Paragraph newParagraph = new Paragraph() { FontWeight = fontWeight };

                            XmlNodeList textNodes = paragraphNode.SelectNodes(XmlTags.TextTag);
                            if (textNodes == null || textNodes.Count <= 0)
                            {
                                mainDoc.Blocks.Add(newParagraph);//添加个空段。
                                continue;
                            }
                            else
                            {
                                foreach (XmlNode textNode in textNodes)
                                {
                                    Run run = new Run(textNode.InnerText);

                                    XmlAttribute attrBackColor = textNode.GetAttribute(XmlTags.BackColorTag);
                                    if (attrBackColor != null)
                                    {
                                        if (attrBackColor.Value == XmlTags.StreamerTag)
                                            run.Background = BrushManager.GetBrush(attrBackColor.Value);
                                        else
                                        {
                                            var bc = BrushManager.GetBrush(attrBackColor.Value);
                                            if (bc != null) run.Background = bc;
                                        }
                                    }

                                    XmlAttribute attrForeColor = textNode.GetAttribute(XmlTags.ForeColorTag);
                                    if (attrForeColor != null)
                                    {
                                        if (attrForeColor.Value == BrushManager.GetName(BrushManager.AntiStreamer))
                                        {
                                            run.Foreground = BrushManager.AntiStreamer;
                                        }
                                        else
                                        {
                                            var fc = BrushManager.GetBrush(attrForeColor.Value);
                                            if (fc != null) run.Foreground = fc;
                                        }
                                    }


                                    var attrFontStyle = textNode.GetAttribute(XmlTags.FontStyleTag);
                                    if (attrFontStyle != null)
                                    {
                                        if (attrFontStyle.Value == "" || attrFontStyle.Value == "Normal") run.FontStyle = FontStyles.Normal;
                                        else if (attrFontStyle.Value == "Italic") run.FontStyle = FontStyles.Italic;
                                        else if (attrFontStyle.Value == "Oblique") run.FontStyle = FontStyles.Oblique;
                                    }
                                    else
                                    {
                                        run.FontStyle = FontStyles.Normal;
                                    }

                                    var attrFontWeight = textNode.GetAttribute(XmlTags.FontWeightTag);
                                    if (attrFontWeight != null)
                                    {
                                        if (attrFontWeight.Value == "" || attrFontWeight.Value == "Normal") run.FontWeight = FontWeights.Normal;
                                        else run.FontWeight = FontWeights.Bold;

                                    }
                                    else
                                    {
                                        run.FontWeight = fontWeight;
                                    }

                                    var attrFontSize = textNode.GetAttribute(XmlTags.FontSizeTag);
                                    if (attrFontSize != null && string.IsNullOrEmpty(attrFontSize.Value) == false)
                                    {
                                        var fsize = double.Parse(attrFontSize.Value);
                                        run.FontSize = fsize;
                                    }
                                    else
                                    {
                                        run.FontSize = fontSize;
                                    }

                                    var attrFontName = textNode.GetAttribute(XmlTags.FontNameTag);
                                    if (attrFontName != null && string.IsNullOrEmpty(attrFontName.Value) == false)
                                    {
                                        FontFamily ff = new FontFamily(attrFontName.Value);
                                        if (ff != null)
                                            run.FontFamily = ff;
                                        else run.FontFamily = fontFamily;
                                    }
                                    else run.FontFamily = fontFamily;


                                    newParagraph.Inlines.Add(run);
                                }

                                mainDoc.Blocks.Add(newParagraph);
                            }
                        }

                        mainDoc.FontFamily = mainRTB.FontFamily = fontFamily;
                        mainDoc.FontSize = mainRTB.FontSize = fontSize;
                        mainDoc.FontWeight = mainRTB.FontWeight = fontWeight;

                        break;
                    }
            }
        }

        private void ReadDefaultFontSizeAndFontFamily()
        {
            double defaultFontSize;
            if (Globals.MainWindow == null || Globals.MainWindow.EditorManager == null)
            {
                defaultFontSize = 12;
            }
            else
            {
                defaultFontSize = Globals.MainWindow.EditorManager.DefaultFontSize;
            }

            Widget mainSelWidget = null;
            foreach (Widget w in selectedWidgets)
            {
                if (w.IsMainSelected)
                {
                    mainSelWidget = w;
                    break;
                }
            }

            if (mainSelWidget == null && selectedWidgets.Count > 0)
            {
                mainSelWidget = selectedWidgets[0];
            }

            mainDoc.FontFamily = mainRTB.FontFamily = TitleManager.GetFontFamily(mainSelWidget.TitleLevel);
            mainDoc.FontSize = mainRTB.FontSize = TitleManager.GetFontSize(mainSelWidget.TitleLevel);
            mainDoc.FontWeight = mainRTB.FontWeight = TitleManager.GetFontWeight(mainSelWidget.TitleLevel);

            if (defaultFontSize > 15)
            {
                foreach (FontInfo fontInfo in cbFont.Items)
                {
                    if (fontInfo.FontName == "Microsoft YaHei")
                    {
                        cbFont.SelectedItem = fontInfo;
                    }
                }
            }
            else
            {
                foreach (FontInfo fontInfo in cbFont.Items)
                {
                    if (fontInfo.FontName == "SimSun")
                    {
                        cbFont.SelectedItem = fontInfo;
                    }
                }
            }
        }

        private static FontFamily font_SimSun = new FontFamily("SimSun");

        private static FontFamily font_MicrosoftYaHei = new FontFamily("Microsoft YaHei");

        /// <summary>
        /// 读取一段文本的内容。
        /// </summary>
        /// <param name="mainRTBFontSetted">是否设置编辑器的字号。</param>
        /// <param name="textNodes">TextArea的后台Xml数据中某个Paragraph节点的某个Text子节点。</param>
        /// <returns></returns>
        private bool ReadOneParagraph(bool mainRTBFontSetted,
            XmlNodeList textNodes, TextAlignment alignment)
        {
            Paragraph newParagraph = new Paragraph() { TextAlignment = alignment };

            foreach (XmlNode textNode in textNodes)
            {
                Run run = new Run(textNode.InnerText);

                //读取出所有格式信息。
                //取文本特性
                XmlAttribute attrForeground = textNode.GetAttribute(XmlTags.ForeColorTag);
                if (attrForeground != null)
                {
                    Brush foreground = Tools.BrushManager.GetBrush(attrForeground.Value);
                    if (foreground != null)
                        run.Foreground = foreground;
                }

                XmlAttribute attrBackground = textNode.GetAttribute(XmlTags.BackColorTag);
                if (attrBackground != null)
                {
                    Brush background = Tools.BrushManager.GetBrush(attrBackground.Value);
                    if (background != null)
                        run.Background = background;
                }
                else
                {
                    run.Background = Brushes.Transparent;
                }

                XmlAttribute attrFontName = textNode.GetAttribute(XmlTags.FontNameTag);
                XmlAttribute attrFontSize = textNode.GetAttribute(XmlTags.FontSizeTag);

                double fontSize;
                if (attrFontSize == null)
                {
                    if (Globals.MainWindow != null && Globals.MainWindow.EditorManager != null)
                    {
                        fontSize = Globals.MainWindow.EditorManager.DefaultFontSize;
                    }
                    else fontSize = 12;
                }
                else
                {
                    fontSize = double.Parse(attrFontSize.Value);
                }

                if (attrFontName != null)
                {
                    FontFamily fontFamily = new FontFamily(attrFontName.Value);
                    if (fontFamily != null)
                        run.FontFamily = fontFamily;

                    if (mainRTBFontSetted == false)
                    {
                        //初始化字体。
                        //foreach (ComboFontItem cfi in cbFont.Items)
                        //{
                        //    if (cfi.FontName == attrFontName.Value)
                        //    {
                        //        cbFont.SelectedItem = cfi;
                        //    }
                        //}
                    }
                }
                else
                {
                    if (fontSize > 15)
                    {
                        run.FontFamily = font_MicrosoftYaHei;
                    }
                    else
                    {
                        run.FontFamily = font_SimSun;
                    }
                }

                //注意，因为fontName和fontSize共用第一个参数值。因此要先读取FontName。

                run.FontSize = fontSize;
                if (mainRTBFontSetted == false)
                {
                    newParagraph.FontSize = mainRTB.FontSize = run.FontSize;
                    mainRTBFontSetted = true;

                    //foreach (ComboBoxItem ci in cbFontSize.Items)
                    //{
                    //    if (((ci as ComboBoxItem).Content as string) == fontSize.ToString())
                    //    {
                    //        cbFontSize.SelectedItem = ci;
                    //        break;
                    //    }
                    //}

                    #region 取首个文本碎片的字型，若没有，按字号大小取默认值。
                    if (attrFontName == null)//若非null,前面已经设置过了。必要
                    {
                        if (run.FontSize > 15)
                        {
                            mainRTB.FontFamily = font_MicrosoftYaHei;

                            //foreach (ComboFontItem fontNameItem in cbFont.Items)
                            //{
                            //    if (fontNameItem.FontName == "Microsoft YaHei")
                            //    {
                            //        cbFont.SelectedItem = fontNameItem;
                            //        break;
                            //    }
                            //}
                        }
                        else
                        {
                            mainRTB.FontFamily = font_SimSun;

                            //foreach (ComboFontItem fontNameItem in cbFont.Items)
                            //{
                            //    if (fontNameItem.FontName == "SimSun")
                            //    {
                            //        cbFont.SelectedItem = fontNameItem;
                            //        break;
                            //    }
                            //}
                        }
                    }
                    #endregion
                }

                XmlAttribute attrFontWeight = textNode.GetAttribute(XmlTags.FontWeightTag);
                if (attrFontWeight != null && attrFontWeight.Value == XmlTags.BoldTag)
                {
                    run.FontWeight = FontWeights.Bold;
                    if (run.FontWeight != fontWeightAfterReaded)
                    {
                        if (fontWeightAfterReaded != null)
                        {
                            fontWeightIsSame = false;
                        }

                        fontWeightAfterReaded = run.FontWeight;
                    }
                }
                else
                {
                    run.FontWeight = FontWeights.Normal;
                    if (run.FontWeight != fontWeightAfterReaded)
                    {
                        if (fontWeightAfterReaded != null)
                        {
                            fontWeightIsSame = false;
                        }

                        fontWeightAfterReaded = run.FontWeight;
                    }
                }

                XmlAttribute attrFontStyle = textNode.GetAttribute(XmlTags.FontStyleTag);
                if (attrFontStyle != null && attrFontStyle.Value == XmlTags.ItalicTag)
                {
                    run.FontStyle = FontStyles.Italic;
                }

                XmlAttribute attrUnderLine = textNode.GetAttribute(XmlTags.UnderLineTag);
                if (attrUnderLine != null && attrUnderLine.Value == true.ToString())
                {
                    run.TextDecorations.Add(TextDecorations.Underline);
                }

                XmlAttribute attrStrikeLine = textNode.GetAttribute(XmlTags.StrikeLineTag);
                if (attrStrikeLine != null && attrStrikeLine.Value == true.ToString())
                {
                    run.TextDecorations.Add(TextDecorations.Strikethrough);
                }

                XmlAttribute attrBaseLineAlignment = textNode.GetAttribute(XmlTags.BaseLineAlignmentTag);
                if (attrBaseLineAlignment != null)
                {
                    switch (attrBaseLineAlignment.Value)
                    {
                        case "Top":
                            {
                                run.BaselineAlignment = BaselineAlignment.Top;
                                run.FontSize = mainRTB.FontSize / 2;
                                break;
                            }
                        case "Bottom":
                            {
                                run.BaselineAlignment = BaselineAlignment.Bottom;
                                run.FontSize = mainRTB.FontSize / 2;
                                break;
                            }
                        default:
                            {
                                run.BaselineAlignment = BaselineAlignment.Baseline;
                                break;
                            }
                    }
                }

                newParagraph.Inlines.Add(run);

                mainDoc.Blocks.Add(newParagraph);
            }
            return mainRTBFontSetted;
        }

        private void SetTextColor(ColorPicker.Destination dest, Brush newBrush)
        {
            switch (dest)
            {
                case ColorPicker.Destination.ForeColor:
                    {
                        TextRange range = new TextRange(mainRTB.Selection.Start, mainRTB.Selection.End);
                        range.ApplyPropertyValue(FlowDocument.ForegroundProperty, newBrush);
                        break;
                    }
                case ColorPicker.Destination.BackColor:
                    {
                        TextRange range = new TextRange(mainRTB.Selection.Start, mainRTB.Selection.End);
                        range.ApplyPropertyValue(FlowDocument.BackgroundProperty, newBrush);
                        break;
                    }
            }
        }

        private string initializedText = null;

        private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            //bool isShift = false, isCtrl = false;
            //KeyboardDevice kd = e.KeyboardDevice;

            //if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
            //    (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            //{
            //    isShift = true;
            //}

            //if ((kd.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 ||
            //    (kd.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0)
            //{
            //    isCtrl = true;
            //}

            //Enter、esc不能放在这里。
        }

        /// <summary>
        /// 向目标部件（不包括鱼骨线等不需要、不支持文本的部件——鱼骨线是折线的特殊形态）写入后台数据。
        /// </summary>
        /// <returns></returns>
        private bool WriteLinesToAllWidgetsXmlData()
        {
            EditorManager manager = Globals.MainWindow.EditorManager;
            if (manager == null) return false;
            PageEditor mainPageEditor = manager.GetMainSelectedPageEditor();
            if (mainPageEditor == null) return false;

            //取出所有需要刷新位置的关系线。
            List<ILinkableLine> linkedLines = mainPageEditor.GetLinkedLines(this.selectedWidgets);

            ModifingInfo info = new ModifingInfo();
            info.ModifingDescription = "设置（编辑）文本内容";
            manager.GetSelectedPageEditorStatus(info);
            manager.GetSelectedWidgetStatus_Old(info);
            manager.GetSelectedWidgetStatus_New(info);

            ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

            int fishBoneWidgetsCount = 0;//折线作鱼骨线时，禁止编辑文本。

            foreach (Widgets.Widget w in selectedWidgets)
            {
                Widgets.ContentWidget cw = w as Widgets.ContentWidget;
                if (cw == null)
                {
                    Widgets.PolyLineWidget pw = w as Widgets.PolyLineWidget;
                    if (pw != null)
                    {
                        if (pw.LineForm == Enums.PolyLineForms.BigFishBone ||
                            pw.LineForm == Enums.PolyLineForms.MediumFishBone)
                        {
                            fishBoneWidgetsCount++;
                            continue;//禁止编辑鱼骨线文本。
                        }
                    }

                    if (WriteLinesToOneWidgetXmlData(mi, w) == false) return false;

                    Widgets.RectangleWidget rw = w as Widgets.RectangleWidget;
                    if (rw == null)
                    {
                        w.InvalidateArrange(); w.UpdateLayout();
                        continue;
                    }
                    else
                    {
                        Widgets.RectangleWidget.ResetRectangleWidgetHeight(mi, rw);
                        continue;
                    }
                }

                if (titleLevel.HasValue && w.TitleLevel != titleLevel.Value)
                {
                    Action actTitleLevel = new Action(w.MasterEditor.Id, w.Id, w.GetType().Name,
                        XmlTags.TitleLevelTag, w.TitleLevel.ToString(), titleLevel.Value.ToString());
                    w.TitleLevel = titleLevel.Value;
                    mi.AddAction(actTitleLevel);
                }


                //如果是文本块且被挂接，自动保持过去的中心。
                //2014年7月5日，修改此行为：如果只有直线连接，则保持中心，否则左对齐。
                if (cw.IsLinked)
                {
                    bool hasNotStraitLinkedLine = false;
                    var cwLinkedLines = cw.GetLinkedLines();
                    foreach (var l in cwLinkedLines)
                    {
                        if (l is StraitLineWidget) continue;
                        else
                        {
                            hasNotStraitLinkedLine = true; break;
                        }
                    }

                    Point oldTopLeft = cw.TopLeft;
                    Point oldBottomRight = cw.BottomRight;//备用

                    //注意顺序
                    if (WriteLinesToOneWidgetXmlData(mi, w) == false) return false;

                    if (hasNotStraitLinkedLine == false)
                    {
                        Point oldCenter = new Point(oldTopLeft.X + (oldBottomRight.X - oldTopLeft.X) / 2,
                            oldTopLeft.Y + (oldBottomRight.Y - oldTopLeft.Y) / 2);
                        cw.InvalidateArrange(); cw.UpdateLayout();

                        Point newTopLeft = cw.TopLeft;
                        Point newBottomRight = cw.BottomRight;
                        Point newLocation = new Point(oldCenter.X - (newBottomRight.X - newTopLeft.X) / 2,
                            oldCenter.Y - (newBottomRight.Y - newTopLeft.Y) / 2);

                        Action actNewLocation = new Action(cw.MasterEditor.Id, cw.Id, cw.GetType().Name, XmlTags.LocationTag,
                            cw.Location.ToString(), newLocation.ToString());
                        cw.Location = newLocation;
                        mi.AddAction(actNewLocation);
                    }
                }
                else
                {
                    if (WriteLinesToOneWidgetXmlData(mi, w) == false) return false;
                }
            }

            //刷新所有需要刷新位置的关系线。
            mainPageEditor.RefreshLinkedLines(mi, linkedLines);

            manager.RegisterModifingItem(mi);
            manager.RefreshAutoNumberStrings();

            if (fishBoneWidgetsCount > 0)
            {
                LunarMessage.Warning(string.Format("　　有 {0} 个部件是处于鱼骨线形态的折线部件，不允许编辑文本。已忽略。",
                    fishBoneWidgetsCount));
            }

            return true;
        }

        /// <summary>
        /// 向某一个目标文本块写入Xml数据。由WriteLinesToAllTextAreaXmlData()方法调用。
        /// </summary>
        private bool WriteLinesToOneWidgetXmlData(ModifingItem<Action, ModifingInfo> mi, Widgets.Widget w)
        {
            if (w == null || w.XmlData == null)
            {
                MessageBox.Show("　　发现意外错误，没有传入部件，或传入的部件没有后台数据节点！",
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;
            }

            StringBuilder sb = new StringBuilder();

            foreach (Block block in mainDoc.Blocks)
            {
                Paragraph paragraph = block as Paragraph;
                if (paragraph == null) continue;

                sb.Append("<" + XmlTags.ParagraphTag + " " + XmlTags.TextAlignmentTag + "=\"" + paragraph.TextAlignment.ToString() + "\">");

                BuildOneParagraphInnerXml(sb, paragraph);

                sb.Append("</" + XmlTags.ParagraphTag + ">");
            }

            string s = sb.ToString();
            if (s.EndsWith("<" + XmlTags.ParagraphTag + "></" + XmlTags.ParagraphTag + ">"))
            {
                s = s.Substring(0, s.Length - 23);
            }

            XmlNode paragraphSetNode = w.XmlData.SelectSingleNode(XmlTags.ParagraphSetTag);
            if (paragraphSetNode == null)
            {
                paragraphSetNode = w.XmlData.AppendXmlAsChild("<" + XmlTags.ParagraphSetTag + " />");
            }

            if (paragraphSetNode == null)
            {
                MessageBox.Show("　　发生意外，没有找到部件的ParagraphSet节点，且无法添加。编辑文本操作失败。",
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            Action actXmlDataInnerXml = new Action(w.MasterEditor.Id, w.Id, w.GetType().Name,
                XmlTags.XmlDataInnerXml, paragraphSetNode.InnerXml, s);

            //注意此处的顺序。不能在Action之前清除。
            paragraphSetNode.InnerXml = "";//先清除所有子节点。

            w.XmlDataInnerXml = s;

            mi.AddAction(actXmlDataInnerXml);

            return true;
        }

        #endregion

        private void cbStyle_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            mainRTB.SelectAll();

            if (cbStyle.SelectedItem == null) return;

            ComboBoxItem cbi = cbStyle.SelectedItem as ComboBoxItem;
            if (cbi == null) return;

            if (cbi.Tag == null) return;

            //格式化为标题文本
            //此方法会记录this.titleLevel的值，以用于完成编辑时更改各目标部件的TitleLevel值。
            FormatAsTitle((Enums.TitleStyle)Enum.Parse(typeof(Enums.TitleStyle), cbi.Tag as string));

            mainRTB.Focus();
        }

        private void btnStreamerBack_Click(object sender, RoutedEventArgs e)
        {
            TextRange range = new TextRange(mainRTB.Selection.Start, mainRTB.Selection.End);
            range.ApplyPropertyValue(FlowDocument.BackgroundProperty, BrushManager.Streamer);
            range.ApplyPropertyValue(FlowDocument.ForegroundProperty, BrushManager.AntiStreamer);
        }

        private void CbxQuickCommandBox_GotFocus(object sender, RoutedEventArgs e)
        {
            CbxQuickCommandBox.Background = Brushes.White;
            CbxQuickCommandBox.Foreground = Brushes.Black;
            Globals.SwitchInputMethod(false);//命令一般用英文字母（即使汉语拼音也比汉字快些），快捷些。
        }

        private void CbxQuickCommandBox_LostFocus(object sender, RoutedEventArgs e)
        {
            CbxQuickCommandBox.Background = Globals.TextCommandInputBoxBackground;
            //CbxQuickCommandBox.Text = string.Empty;//不能用这个，会造成“历史命令”失效。
            CbxQuickCommandBox.Foreground = Brushes.Transparent;
        }

        private void CbxQuickCommandBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                //执行命令

                mainRTB.Focus();

                //如果去除空格之后啥都没有，直接返回，什么都不做。
                string tmp = CbxQuickCommandBox.Text;
                tmp = tmp.Replace("　", " "); tmp = tmp.Replace("_", " "); tmp = tmp.Replace("/", " ");
                tmp = tmp.Trim();
                if (tmp.Length <= 0) { mainRTB.Focus(); CbxQuickCommandBox.Text = string.Empty; return; }

                string resultOfCommand = RunQuickTextCommand(CbxQuickCommandBox.Text);

                //如果执行成功，返回主界面，命令窗口失去焦点。
                //如果执行失败，显示错误消息。


                if (resultOfCommand != string.Empty)
                {
                    MessageBox.Show("　　命令执行失败！错误消息：\r\n\r\n　　" + resultOfCommand,
                        Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    CbxQuickCommandBox.Focus();
                    return;
                }


                //执行成功，将使用过的命令临时存储起来。
                CbxQuickCommandBox.Items.Insert(0, CbxQuickCommandBox.Text);
                CbxQuickCommandBox.Text = string.Empty;

                commandPanel.Visibility = System.Windows.Visibility.Hidden;
            }
            else if (e.Key == Key.Escape)
            {
                commandPanel.Visibility = System.Windows.Visibility.Hidden;
                mainRTB.Focus();
            }
        }

        private string RunQuickTextCommand(string commandText)
        {
            char[] whiteChars = new char[] { ' ', '　', '\t', };
            commandText = RunTextCommand.FormatUserInputedCommandText(commandText.ToLower().TrimStart(whiteChars));

            if (commandText.StartsWith("前景色") ||
                commandText.StartsWith("文本色") ||
                commandText.StartsWith("文字色") ||
                commandText.StartsWith("字色") ||
                commandText.StartsWith("zs") ||
                commandText.StartsWith("qjs") ||
                commandText.StartsWith("wbs") ||
                commandText.StartsWith("wzs"))
            {
                if (mainRTB.Selection.Text.Length <= 0) return "　　请先选定文本。";

                var indexOfSpace = commandText.IndexOf(' ');
                var subTextOfColorParameter = commandText.Substring(indexOfSpace).Trim(whiteChars);

                Brush brush = BrushManager.GetBrush(subTextOfColorParameter);
                if (brush == null)
                {
                    brush = BrushManager.GetBrushByChineseName(subTextOfColorParameter);
                }

                if (brush == null) return "　　未能找到此种色彩！";

                SetTextColor(ColorPicker.Destination.ForeColor, brush);
                return string.Empty;
            }

            if (commandText.StartsWith("背景色") ||
                commandText.StartsWith("文本背景色") ||
                commandText.StartsWith("底色") ||
                commandText.StartsWith("bjs") ||
                commandText.StartsWith("wbbjs") ||
                commandText.StartsWith("ds") ||
                commandText.StartsWith("wbds") ||
                commandText.StartsWith("wzds"))
            {
                if (mainRTB.Selection.Text.Length <= 0) return "　　请先选定文本。";

                var indexOfSpace = commandText.IndexOf(' ');
                var subTextOfColorParameter = commandText.Substring(indexOfSpace).Trim(whiteChars);

                Brush brush = BrushManager.GetBrush(subTextOfColorParameter);
                if (brush == null)
                {
                    brush = BrushManager.GetBrushByChineseName(subTextOfColorParameter);
                }

                if (brush == null) return "　　未能找到此种色彩！";

                SetTextColor(ColorPicker.Destination.BackColor, brush);
                return string.Empty;
            }

            if (commandText.StartsWith("字号") ||
                commandText.StartsWith("fontsize") ||
                commandText.StartsWith("zh"))
            {
                if (mainRTB.Selection.Text.Length <= 0) return "　　请先选定文本。";

                var indexOfSpace = commandText.IndexOf(' ');
                var subTextOfFontSize = commandText.Substring(indexOfSpace).Trim(whiteChars);
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty,
                    double.Parse(subTextOfFontSize));
                return string.Empty;
            }

            if (commandText.StartsWith("字体") ||
                commandText.StartsWith("fontname") ||
                commandText.StartsWith("zt") ||
                commandText.StartsWith("fontfamily") ||
                commandText.StartsWith("font"))
            {
                if (mainRTB.Selection.Text.Length <= 0) return "　　请先选定文本。";

                var indexOfSpace = commandText.IndexOf(' ');
                var subTextOfFontName = commandText.Substring(indexOfSpace).TrimStart(whiteChars).TrimEnd(whiteChars);

                bool valid = false;
                foreach (FontInfo item in cbFont.Items)
                {
                    if (item.FontName.ToLower() == subTextOfFontName.ToLower() || item.LocalFontName.ToLower() == subTextOfFontName.ToLower())
                    {
                        cbFont.SelectedItem = item;//会自动更改字体。
                        valid = true;
                        break;
                    }
                }

                if (!valid) return "　　不是有效的字体名称！";

                return string.Empty;
            }

            switch (commandText)
            {
                case "bold":
                case "加粗":
                    {
                        btnBold_Click(null, null);
                        return string.Empty;
                    }
                case "underline":
                case "下划线":
                    {
                        btnStrikeLine_Click(null, null);
                        return string.Empty;
                    }
                case "italic":
                case "倾斜":
                    {
                        btnItalic_Click(null, null);
                        return string.Empty;
                    }
                default:
                    {
                        return "　　不能识别命令！";
                    }
            }
        }

        private void BtnTextCommand_Click(object sender, RoutedEventArgs e)
        {
            LunarMessage.Information("　　输入命令后回车即可执行。主要用于支持快速设定文字色彩。");
        }

    }

    /// <summary>
    /// 组合框类使用的项目。2012年8月5日之前更换了取系统字体使用的类。不需要此类了。
    /// </summary>
    //class ComboFontItem : ComboBoxItem
    //{
    //    public ComboFontItem(string fontName, System.Windows.Media.FontFamily newFontFamily)
    //    {
    //        this.RelativeFontFamily = newFontFamily;
    //        this.Content = fontName;
    //    }

    //    private FontFamily RelativeFontFamily { get; set; }

    //    public string FontName
    //    {
    //        get
    //        {
    //            return RelativeFontFamily.FamilyNames[XmlLanguage.GetLanguage("en-us")].ToString();
    //        }
    //    }
    //}
}
